package com.woshua.splashmodel.view;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.view.View;
import android.view.animation.LinearInterpolator;
import android.view.animation.OvershootInterpolator;

import com.woshua.splashmodel.R;

public class SplashView extends View {

    private int[] mCircleColors;

    private float mRotationRadius=140;

    private float mCircleRadius=25;

    private float mCenterX;
    private float mCenterY;

    private Paint mPaint=new Paint();
    private Paint mPaintBg=new Paint();

    private SplashState mState;
    private float mDiagnaDist;

    public SplashView(Context context) {
        super(context);

        init(context);
    }

    private void init(Context context) {
        mCircleColors=context.getResources().getIntArray(R.array.splash_circle_colors);

        mPaint.setAntiAlias(true);
        mPaintBg.setAntiAlias(true);

        mPaintBg.setColor(getResources().getColor(R.color.splash_bg));

        mPaintBg.setStyle(Paint.Style.STROKE);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);

        mCenterX=w/2f;
        mCenterY=h/2f;
        mDiagnaDist = (float) (Math.sqrt(w*w+h*h)/2);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        if(mState==null)
        {
            mState=new RotationState();
        }
        mState.drawState(canvas);
        super.onDraw(canvas);
    }

    private abstract class SplashState
    {
        public abstract void drawState(Canvas canvas);
    }

    /*
    * 旋转动画
    * */
    public long mRotationDuration=1200;
    private float mCurrentRotationAngel;
    private class RotationState extends SplashState
    {

        private ValueAnimator valueAnimator;

        public RotationState() {
            valueAnimator=ValueAnimator.ofFloat(0f, (float) (Math.PI*2));
            valueAnimator.setDuration(mRotationDuration);
            valueAnimator.setInterpolator(new LinearInterpolator());
            valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator animation) {
                    mCurrentRotationAngel = (float) animation.getAnimatedValue();

                    invalidate();
                }
            });

            valueAnimator.setRepeatCount(ValueAnimator.INFINITE);
            valueAnimator.start();
        }

        @Override
        public void drawState(Canvas canvas) {
            drawBackground(canvas);
            //定时器不断获取大圆的角度
            drawCircle(canvas);
        }

        public void stop() {
            valueAnimator.cancel();
        }
    }

    /*
    * 聚合动画
    * */
    private float mCurrentRotationRadius=mRotationRadius;
    private class MergingState extends SplashState
    {
        private ValueAnimator valueAnimator;

        public MergingState() {
//            大圆半径到0
            valueAnimator=ValueAnimator.ofFloat(0f, mRotationRadius);
            valueAnimator.setDuration(mRotationDuration/2);
            valueAnimator.setInterpolator(new OvershootInterpolator());
            valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator animation) {
                    mCurrentRotationRadius = (float) animation.getAnimatedValue();

                    invalidate();
                }
            });

            valueAnimator.addListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationEnd(Animator animation) {
                    super.onAnimationEnd(animation);
                    //开始下一个
                    mState=new ExpandState();
                }
            });
            valueAnimator.reverse();
        }

        @Override
        public void drawState(Canvas canvas) {
            drawBackground(canvas);
            //定时器不断获取大圆的角度
            drawCircle(canvas);
        }
    }

    /*
    * 扩散动画
    * */
    private float mHoleRadius=0;

    private class ExpandState extends SplashState
    {
        private ValueAnimator valueAnimator;

        public ExpandState() {
            valueAnimator=ValueAnimator.ofFloat(0f,mDiagnaDist);
            valueAnimator.setDuration(mRotationDuration/2);
            valueAnimator.setInterpolator(new LinearInterpolator());
            valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator animation) {
                    mHoleRadius = (float) animation.getAnimatedValue();

                    invalidate();
                }
            });

            valueAnimator.start();
        }

        @Override
        public void drawState(Canvas canvas) {
            drawBackground(canvas);
        }
    }

    private void drawBackground(Canvas canvas) {
        if(mHoleRadius>0)
        {
            float stockWidth=mDiagnaDist-mHoleRadius;
            mPaintBg.setStrokeWidth(stockWidth);
            float radius=mHoleRadius+stockWidth/2;
            canvas.drawCircle(mCenterX,mCenterY,radius,mPaintBg);
        }
        else
        {
            canvas.drawColor(Color.WHITE);
        }

    }

    private void drawCircle(Canvas canvas) {
        float rotationAngel=(float)(2*Math.PI/mCircleColors.length);

        for (int i = 0; i < mCircleColors.length; i++) {
            double angle=i*rotationAngel+mCurrentRotationAngel;
            float cx= (float) (mCenterX+mCurrentRotationRadius*Math.cos(angle));
            float cy= (float) (mCenterY+mCurrentRotationRadius*Math.sin(angle));

            mPaint.setColor(mCircleColors[i]);
            canvas.drawCircle(cx,cy,mCircleRadius,mPaint);
        }
    }

    public void stopSplashAndJumpToMain()
    {
        if(mState!=null && mState instanceof RotationState)
        {
            RotationState rotationState= (RotationState) mState;
            rotationState.stop();

            post(new Runnable() {
                @Override
                public void run() {
                    mState=new MergingState();
                }
            });
        }
    }
}
